// Copyright (C) 2022 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
//
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<广西木子科技有限公司>，授权编号：<NT220402151538>，代码指纹：<A.648883738.885>，技术对接人微信：<ID: Lingmuziyi>】
// 【授权寄送：<收件：李先生、地址：南宁市科园西十路11号国电智能大厦1101F、电话：17736659550、邮箱：yingshashou@vip.qq.com>】
//
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
//
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rainbowchat.http.logic;

import net.x52im.mobileimsdk.server.processor.OnlineProcessor;
import net.x52im.mobileimsdk.server.protocal.Protocal;
import net.x52im.mobileimsdk.server.protocal.ProtocalFactory;

import com.alibaba.fastjson.JSONObject;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.Processor;
import com.eva.framework.dbpool.DBShell;
import com.eva.framework.dto.SysActionConst;
import com.eva.framework.utils.EndsExceptionFactory;
import com.eva.framework.utils.LoggerFactory;
import com.x52im.rainbowchat.common.dto.cnst.UserProtocalsType;
import com.x52im.rainbowchat.im.impl.ChatLogicManager;

/**
 * 服务端对外提供的实时消息推送等特权接口处理器。
 * <p>
 * 此处理器内的接口均为用于管理端的特权接口，原则上客户端禁止调用。
 *
 * @author Jack Jiang(http://www.52im.net/space-uid-1.html)
 * @version 1.0
 * @since 4.0
 */
public class IMAdminProcessor implements SysActionConst, Processor {
    public static DBShell db = new DBShell();

    /**
     * 处理器的核心实现方法.<br>
     * 可据job_dispatch_id找到对应的JobDispatcher，JobDispatcher又能据
     * action_id进行对应动作的处理，以完成本次操作请求.
     *
     * @param job_dispatch_id 作业调度ID
     * @param action_id       动作ID
     * @param Object          newData 客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
     * @param Object          oldData 客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
     * @param UserRoot        user 包含该请求用户完整个人信息封装对象（该对象来自于成功登陆后存放于session中的值）
     * @return 任意类型返回值
     * @throws Exception
     */
    @Override
    public Object process(int job_dispatch_id, int action_id, Object _newData, Object _oldData, User user)
            throws Exception {
        Object ret = null;
        String newDataJSON = (String) _newData;

        switch (job_dispatch_id) {
            // 处理服务端对外提供的实时消息推送接口的管理
            case com.x52im.rainbowchat.http.logic.dto.JobDispatchConst.LOGIC_MSG$PUSH:
                ret = maintainMgrMsg$PushJobDispatcher(action_id, newDataJSON, _oldData, user);
                break;

            default:
                throw EndsExceptionFactory.INVALID_JOB_DISPATCHER_ID(job_dispatch_id);
        }
        return ret;
    }

    /**
     * 维护服务端对外提供的实时消息推送接口的管理.
     *
     * @param action_id           维护类型，SysConstant中的操作类型常量
     * @param newData             客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
     * @param oldData             客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
     * @param userName            操作者的用户名
     * @param userForUploadPVoice true表示上传的是个我介绍的语音文件
     * @return 返回给客户端的对象
     */
    public Object maintainMgrMsg$PushJobDispatcher(int action_id
            , String newDataJSON, Object oldData, User user) throws Exception {
        switch (action_id) {
            // 向指定客户端推送一条消息或指令（目前暂时用作网页管理端调用，请注意安全性）
            case ACTION_APPEND1: {
                // 客户端传过来的数据
                JSONObject nwObj = JSONObject.parseObject(newDataJSON);

                // 消息发送者的uid（必须是RainbowChat用户表中已存在的用户）
                String from = nwObj.getString("from");
                // 消息接收者的uid（必须是RainbowChat用户表中已存在的用户）
                String to = nwObj.getString("to");
                // 消息内容，是 MsgBody4Guest 类的JSON文本内容
                // 见：http://docs.52im.net/extend/docs/api/rainbowchatserver4_pro/com/x52im/rainbowchat/im/dto/MsgBody4Guest.html
                String dataContent = nwObj.getString("dataContent");
                // 0 表示false、1表示true，建议填“1”
                boolean QoS = "1".equals(nwObj.getString("QoS"));// 0 表示false、1表示true
                // 消息类型，参见：MsgBodyRoot 类中的“聊天消息类型”常量定义
                // 见：http://docs.52im.net/extend/docs/api/rainbowchatserver4_pro/com/x52im/rainbowchat/im/dto/MsgBodyRoot.html
                int typeu = CommonUtils.getIntValue(nwObj.getString("typeu"), -1);

                boolean result = false;

                // 如果是模拟客户端发送临时聊天消息则调用以下方法
                if (typeu == UserProtocalsType.MT43_OF_TEMP$CHAT$MSG_SERVER$TO$B) {
                    // 以下方法是完整的RainbowChat临时聊天消息发送方式，包含了离线处理等异常情况
                    result = ChatLogicManager.processMT42_OF_TEMP$CHAT$MSG_A$TO$SERVER(Protocal.genFingerPrint(), dataContent);
                }
                // 其它特权消息请根据实际情况决定是否要离线处理等特殊情况
                else {
                    Protocal p = ProtocalFactory.createCommonData(dataContent
                            , from, to, QoS, Protocal.genFingerPrint(), typeu);

                    // 首先判断消息接收者是否在线
                    if (OnlineProcessor.isOnline(to)) {
                        // 以下方法是用于实时消息发送的
//						result = MessageHelper.sendMessage(from, to, dataContent, QoS, typeu);
//						result = LocalSendHelper.sendData(p);
                        result = true;
                    }
                    // 如果接收者不在线的话，特权指令的处理情况有待进一步约定
                    else {
                        LoggerFactory.getLog().warn("【特权接口】向客户端" + to
                                + "推送的消息因对方不在线而不能实时发送，应针对不同" +
                                "的特权消息类型考虑离线情况下的处理哦(dataContent=" + dataContent + ")");

                        // TODO 不同类型的特权消息发送需要进一步处理哦！
                    }
                }

                return result ? "1" : "0";
            }

            default:
                throw EndsExceptionFactory.INVALID_ACTION_ID(action_id);
        }
    }
}
